package com.loanapp.server.user.provider.config;

import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.condition.RequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;

/**
 *
 *  Api实现类   url映射到方法名
 *
 */

public class MyRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
    private RequestMappingInfo.BuilderConfiguration config = new RequestMappingInfo.BuilderConfiguration();

    @Override
    protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
        RequestMappingInfo info = this.createRequestMappingInfo(method,method);
        if (info != null) {
            RequestMappingInfo typeInfo = this.createRequestMappingInfo(handlerType,method);
            if (typeInfo != null) {
                info = typeInfo.combine(info);
            }
        }
        return info;
    }

    private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element,Method method) {
        RequestMapping requestMapping = (RequestMapping) AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
        RequestCondition<?> condition = element instanceof Class ? this.getCustomTypeCondition((Class)element) : this.getCustomMethodCondition((Method)element);
        return requestMapping != null ? this.createRequestMappingInfo(method,requestMapping, condition) : null;
    }

    protected RequestMappingInfo createRequestMappingInfo(Method method,RequestMapping requestMapping, RequestCondition<?> customCondition) {
        if(requestMapping.value().length==0){
            requestMapping=this.ret(requestMapping,method.getName());
        }
        return RequestMappingInfo.paths(this.resolveEmbeddedValuesInPatterns(requestMapping.path())).methods(requestMapping.method()).params(requestMapping.params()).headers(requestMapping.headers()).consumes(requestMapping.consumes()).produces(requestMapping.produces()).mappingName(requestMapping.name()).customCondition(customCondition).options(this.config).build();
    }



    private RequestMapping ret(RequestMapping requestMapping,String methodName){
        RequestMapping newre= new RequestMapping() {
            @Override
            public boolean equals(Object obj) {
                return requestMapping.equals(obj);
            }
            @Override
            public int hashCode() {
                return requestMapping.hashCode();
            }

            @Override
            public String toString() {
                return requestMapping.toString();
            }

            @Override
            public Class<? extends Annotation> annotationType() {
                return requestMapping.annotationType();
            }

            @Override
            public String name() {
                return requestMapping.name();
            }

            @Override
            public String[] value() {
                String[] str={methodName};
                return str;
            }
            @Override
            public String[] path() {
                String[] str={methodName};
                return str;
            }
            @Override
            public RequestMethod[] method() {
                return requestMapping.method();
            }

            @Override
            public String[] params() {
                return  requestMapping.params();
            }

            @Override
            public String[] headers() {
                return requestMapping.headers();
            }

            @Override
            public String[] consumes() {
                return requestMapping.consumes();
            }

            @Override
            public String[] produces() {
                return requestMapping.produces();
            }
        };
        return  newre;
    }

}
